#
#  Copyright 2022 The Open Islands Authors. All Rights Reserved.
#
#  Licensed under the Apache License, Version 2.0 (the "License");
#  you may not use this file except in compliance with the License.
#  You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
#  Unless required by applicable law or agreed to in writing, software
#  distributed under the License is distributed on an "AS IS" BASIS,
#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#  See the License for the specific language governing permissions and
#  limitations under the License.
#

import typing

from pyoi.constant import FederatedMode, StorageEngine
from pyoi.context.abc import GarbageCollectionABC
from pyoi.context.abc import MQChannelABC, MQManagerABC
from pyoi.context.types import MQArgs, FederatedPacketRouting
from pyoi.types import FederatedAddress
from pyoi.util.log_utils import getLogger

LOGGER = getLogger()


class BaseContext:
    def __init__(
            self,
            context_id,
            task_id,
            federated_mode: FederatedMode,
            role,
            node_id,
            nodes: typing.Dict[str, typing.List[str]],
            mq_args: MQArgs,
            mq_manager: MQManagerABC,
            default_storage_engine: StorageEngine
    ):
        self._context_id = context_id
        self._task_id = task_id
        self._federated_mode = federated_mode
        self._role = role
        self._node_id = node_id
        self._nodes = nodes
        self._mq_args = mq_args
        self._mq_manager = mq_manager
        self._data_structure = None
        self._default_storage_engine = default_storage_engine

        self._topic_map: typing.Dict[str, FederatedPacketRouting] = {}
        self._channels_map: typing.Dict[str, MQChannelABC] = {}
        self._name_dtype_map = {}
        self._packet_cache = {}

    @property
    def context_id(self):
        return self._context_id

    @property
    def role(self):
        return self._role

    @property
    def node_id(self):
        return self._node_id

    @property
    def nodes(self):
        return self._nodes

    def get(self, name: str, tag: str, src_addresses: typing.List[FederatedAddress],
            gc: GarbageCollectionABC) -> typing.List:
        raise NotImplementedError

    def remote(self, v, name: str, tag: str, dest_addresses: typing.List[FederatedAddress],
               gc: GarbageCollectionABC) -> typing.NoReturn:
        raise NotImplementedError

    def cleanup(self):
        raise NotImplementedError

    def stop(self):
        raise NotImplementedError

    def kill(self):
        raise NotImplementedError

    def __getstate__(self):
        # Avoid serialization
        pass
